<template>
	<div class="container" :style="{ ...container }">
		<div
			class="title-container"
			v-if="props.config.style.titleShow"
			:style="{ justifyContent: props.config.style.align }"
		>
			<div class="flex items-center">
				<i
					:class="['iconfont', props.config.style.titleIcon]"
					:style="{ ...titleIconStyle }"
					v-if="props.config.style.titleIconShow"
				></i>
				<span class="font-7" :style="{ ...titleStyle }">{{ props.config.style.title }}</span>
			</div>
			<div class="flex items-center" v-if="props.config.style.titleEndShow">
				<span class="font-7" :style="{ ...titleEndStyle }">{{ props.config.style.titleEnd }}</span>
				<i
					:class="['iconfont', props.config.style.titleEndIcon]"
					:style="{ ...titleEndIconStyle }"
					v-if="props.config.style.titleEndIconShow"
				></i>
			</div>
		</div>
		<div ref="chartContainer" class="chart-container"></div>
	</div>
</template>

<script setup>
	import config from './config'
	import { ref, onMounted, onBeforeUnmount, nextTick, computed, watchEffect, reactive } from 'vue'
	import { Gauge } from '@antv/g2plot'
	import { cloneDeep } from 'lodash-es'
	import datasetApi from '@/views/plugin/dashboard/api/datasetApi'
	import { observeChartResize, updateChart, cleanupChart } from '@/views/plugin/dashboard/plugin/utils/chartUtils'

	const props = defineProps({
		config: {
			type: Object,
			default: () => config
		},
		previewConfig: {
			type: Object,
			default: () => config
		}
	})

	const chartContainer = ref(null)
	const chartInstance = ref(null)
	const resizeObserver = ref(null)
	// 数据源数据
	const chartData = ref(props.config.data.chartData.value)
	// 百分数
	const percent = ref(props.config.data.percent.value)
	// 旧的dataSetJson 用于比较是否一样就不重新获取数据
	const oldDataSetJson = ref(props.config.dataSetConfig.dataSetJson)
	// 图表配置
	const chartOptions = ref({})

	// 获取数据源数据函数
	const fetchChartData = async (isFlag = false) => {
		const { dataSetType, dataSetJson } = props.config.dataSetConfig
		const isNew = isFlag || JSON.stringify(oldDataSetJson.value) !== JSON.stringify(dataSetJson)
		// 如果是数据源且有效
		if (dataSetType === 1 && dataSetJson && Object.keys(dataSetJson).length > 0 && isNew) {
			try {
				const res = await datasetApi.preview(dataSetJson)
				if (res && res.length > 0) {
					chartData.value = res
					// 如果有指定字段，则使用该字段的值作为进度值
					if (props.config.data.percent.field && res[0][props.config.data.percent.field] !== undefined) {
						percent.value = res[0][props.config.data.percent.field]
					}
				}
			} catch (error) {
				console.error('获取数据源数据失败:', error)
			}
		}

		// 如果是静态数据
		if (dataSetType === 0) {
			chartData.value = props.config.data.chartData.value
			percent.value = props.config.data.percent.value
			return
		}
	}

	// 初始化图表配置
	const setChartOptions = () => {
		chartOptions.value = {
			percent: percent.value,
			radius: props.config.style.radius,
			startAngle: props.config.style.startAngle,
			endAngle: props.config.style.endAngle,
			innerRadius: props.config.style.innerRadius,
			range: {
				ticks: [0, 0.25, 0.5, 0.75, 1],
				color: ['#F4664A', '#FAAD14', '#30BF78'],
				width: props.config.style.range.width
			},
			indicator: {
				pointer: {
					style: {
						stroke: props.config.style.indicator.pointer.style.stroke,
						lineWidth: props.config.style.indicator.pointer.style.lineWidth,
						fill: props.config.style.indicator.pointer.style.fill
					}
				},
				pin: {
					style: {
						stroke: props.config.style.indicator.pin.style.stroke,
						fill: props.config.style.indicator.pin.style.fill,
						r: props.config.style.indicator.pin.style.r
					}
				}
			},
			statistic: {
				title: {
					formatter: ({ percent }) => `${(percent * 100).toFixed(0)}%`,
					style: {
						fontSize: props.config.style.statistic.title.style.fontSize,
						color: props.config.style.statistic.title.style.color,
						fontWeight: props.config.style.statistic.title.style.fontWeight,
						textAlign: props.config.style.statistic.title.style.textAlign
					}
				},
				content: {
					formatter: () => props.config.style.statistic.content.formatter,
					style: {
						fontSize: props.config.style.statistic.content.style.fontSize,
						color: props.config.style.statistic.content.style.color,
						textAlign: props.config.style.statistic.content.style.textAlign
					}
				}
			},
			color: props.config.style.chartColor,
			interactions: [{ type: 'element-active' }]
		}
	}

	// 初始化图表
	const initChart = async () => {
		await nextTick()
		if (chartContainer.value && !chartInstance.value) {
			chartInstance.value = new Gauge(chartContainer.value, chartOptions.value)
			chartInstance.value.render()
		}
	}

	// 暴露给外部的更新配置方法
	const onReload = async (isFlag = false) => {
		// 获取数据
		await fetchChartData(isFlag)
		// 初始化图表配置
		setChartOptions()
		// 更新图表
		if (chartInstance.value) {
			updateChart(chartInstance.value, chartOptions.value)
		} else {
			await initChart()
		}
	}

	// 组件挂载
	onMounted(async () => {
		// 获取数据
		await onReload()
		// 监听容器尺寸变化，使外层卡片拖动时图表能更新
		if (chartContainer.value) {
			resizeObserver.value = observeChartResize(chartContainer.value, chartInstance.value, resizeObserver.value)
		}
	})

	// const initFlag = ref(false)

	// watchEffect(async () => {
	// 	if (!chartInstance.value || initFlag.value === true) return
	// 	// 获取数据
	// 	await fetchChartData()

	// 	// 初始化表单状态
	// 	initFormState()

	// 	// 初始化图表配置
	// 	setChartOptions()

	// 	// 初始化
	// 	await initChart()
	// 	initFlag.value = true
	// })

	// 暴露方法给父组件
	defineExpose({
		onReload
	})

	// 组件卸载前清理
	onBeforeUnmount(() => {
		// 使用通用方法清理图表资源
		cleanupChart(chartInstance.value, resizeObserver.value)
	})

	// 样式计算
	const container = computed(() => ({
		backgroundColor: props.config.style.bgColor,
		backgroundImage: props.config.style.bgImg ? `url(${props.config.style.bgImg})` : 'none',
		borderStyle: props.config.style.borderStyle,
		borderColor: props.config.style.borderColor,
		borderWidth: props.config.style.borderWidth + 'px',
		paddingTop: props.config.style.paddingT + 'px',
		paddingRight: props.config.style.paddingR + 'px',
		paddingBottom: props.config.style.paddingB + 'px',
		paddingLeft: props.config.style.paddingL + 'px',
		borderTopLeftRadius: props.config.style.bgRTL + 'px',
		borderTopRightRadius: props.config.style.bgRTR + 'px',
		borderBottomLeftRadius: props.config.style.bgRBL + 'px',
		borderBottomRightRadius: props.config.style.bgRBR + 'px',
		boxShadow: `${props.config.style.shadowX}px ${props.config.style.shadowY}px ${props.config.style.shadowDegree}px ${props.config.style.shadowColor}`
	}))

	const titleStyle = computed(() => ({
		fontSize: props.config.style.titleSize + 'px',
		color: props.config.style.titleColor,
		fontWeight: props.config.style.titleWeight ? 'bold' : 'normal',
		fontStyle: props.config.style.titleStyle ? 'italic' : 'normal',
		textDecoration: props.config.style.titleLine ? 'underline' : 'none'
	}))

	const titleIconStyle = computed(() => ({
		fontSize: props.config.style.titleIconSize + 'px',
		color: props.config.style.titleIconColor,
		marginRight: '5px'
	}))

	const titleEndStyle = computed(() => ({
		fontSize: props.config.style.titleEndSize + 'px',
		color: props.config.style.titleEndColor,
		fontWeight: props.config.style.titleEndWeight ? 'bold' : 'normal',
		fontStyle: props.config.style.titleEndStyle ? 'italic' : 'normal',
		textDecoration: props.config.style.titleEndLine ? 'underline' : 'none'
	}))

	const titleEndIconStyle = computed(() => ({
		fontSize: props.config.style.titleEndIconSize + 'px',
		color: props.config.style.titleEndIconColor,
		marginLeft: '5px'
	}))
</script>

<style scoped lang="less">
	.container {
		height: 100%;
		width: 100%;
		display: flex;
		flex-direction: column;
	}

	.title-container {
		display: flex;
		align-items: center;
		margin-bottom: 10px;
	}

	.chart-container {
		flex: 1;
		width: 100%;
		min-height: 100px;
	}
</style>
